package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zimi.mapper.*;
import com.zimi.model.*;
import com.zimi.util.MD5Util;
import com.zimi.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 系统用户表 Service
 *
 * @author lnintr
 * @since 2019-05-23
 */
@Service
public class SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserExtendMapper sysUserExtendMapper;
    @Autowired
    private SysPostMapper sysPostMapper;
    @Autowired
    private SysPostUserMapper sysPostUserMapper;
    @Autowired
    private SysOrgMapper sysOrgMapper;
    @Autowired
    private SysOrgExtendMapper sysOrgExtendMapper;

    public List<SysUserExtend> selectUserList(List<String> postIds, String userName) {
        List<SysUserExtend> result = null;

        // 1)取出人员一览
        if (postIds != null && postIds.size() > 0) {
            Map sqlMap = new HashMap();
            SysOrgPostPair sysOrgPostPair = null;
            String[] tmpStrings = null;

            List<SysOrgPostPair> sysOrgPostPairs = new ArrayList<>();
            for (String pi : postIds) {
                tmpStrings = pi.split("-");

                sysOrgPostPair = new SysOrgPostPair();
                sysOrgPostPair.setOrgId(Integer.valueOf(tmpStrings[0]));
                sysOrgPostPair.setPostId(Integer.valueOf(tmpStrings[1]));

                sysOrgPostPairs.add(sysOrgPostPair);
            }

            sqlMap.put("sysOrgPostPairs", sysOrgPostPairs);
            sqlMap.put("userName", userName);
            result = sysUserExtendMapper.selectUserList(sqlMap);

            // 2)取出人员的岗位一览
            if (result != null && result.size() > 0) {
                List<Integer> userIds = new ArrayList<>();
                Map<Integer, SysUserExtend> userMap = new HashMap<>();

                for (SysUserExtend sue : result) {
                    userIds.add(sue.getId());
                    userMap.put(sue.getId(), sue);
                }

                List<SysOrgExtend> sysOrgExtends = sysPostUserMapper.selectPostList(userIds);
                SysUserExtend tmpSysUserExtend = null;
                if (sysOrgExtends != null && sysOrgExtends.size() > 0) {
                    for (SysOrgExtend soe : sysOrgExtends) {
                        tmpSysUserExtend = userMap.get(soe.getUserId());

                        if (tmpSysUserExtend != null) {
                            tmpSysUserExtend.getPostList().add(soe);
                        }
                    }
                }
            }
        } else {
            result = new ArrayList<>();
        }

        return result;
    }

    public List<SysUser> getUsersByIds(List<Integer> res) {
        List<SysUser> result = sysUserMapper.selectList(new QueryWrapper<SysUser>().lambda().in(SysUser::getId, res).eq(SysUser::getUserState, 1));
        return result;
    }

    @Transactional
    public void delete(SysUser sysUser) {
        SysUser result = sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, sysUser.getId()));

        if (result != null) {
            // 1）判断该数据已经被改过没有
            if (result.getUpdateTime() != null) {
                if (sysUser.getUpdateTime() == null) {
                    throw new RuntimeException("保存数据失败，用户数据已经被其他用户改过。");
                } else {
                    if (sysUser.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                        throw new RuntimeException("保存数据失败，用户数据已经被其他用户改过。");
                    }
                }
            }

            SysUser user = UserUtil.getUser();
            Date updateTime = new Date();

            // 2)修改用户数据
            result.setUserState(2);
            result.setUpdateUser(user.getId());
            result.setUpdateTime(updateTime);
            result.updateById();

            // 3)修改岗位用户数据
            SysPostUser sysPostUser = new SysPostUser().setState(2).setUpdateUser(user.getId()).setUpdateTime(updateTime);
            sysPostUserMapper.update(sysPostUser, new UpdateWrapper<SysPostUser>().lambda().eq(SysPostUser::getUserId, result.getId()).eq(SysPostUser::getState, 1));
        } else {
            throw new RuntimeException("保存数据失败，用户数据已经被其他用户改过。");
        }
    }

    @Transactional
    public void update(SysUserExtend sysUserExtend) {
        SysUser sysUser = new SysUser();

        sysUser.setId(sysUserExtend.getId());
        sysUser.setLoginName(sysUserExtend.getLoginName());
        sysUser.setUserName(sysUserExtend.getUserName());
        sysUser.setFileId(sysUserExtend.getFileId() == null ? 0 : sysUserExtend.getFileId());
        sysUser.setUserSex(sysUserExtend.getUserSex());
        sysUser.setUserEmail(sysUserExtend.getUserEmail());
        sysUser.setUserPhone(sysUserExtend.getUserPhone());
        sysUser.setCreateUser(sysUserExtend.getCreateUser());
        sysUser.setCreateTime(sysUserExtend.getCreateTime());
        sysUser.setUpdateUser(sysUserExtend.getUpdateUser());
        sysUser.setUpdateTime(sysUserExtend.getUpdateTime());
        sysUser.setUserState(1);

        // 1)判断登录名,邮箱，手机号不能重复
        SysUser user = sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getLoginName, sysUser.getLoginName()));
        if (user != null && user.getId() != sysUser.getId()) {
            throw new RuntimeException("登录名已被注册过，请换一个登录名重新输入");
        }

        if (sysUser.getUserEmail() != null && sysUser.getUserEmail().length() > 0) {
            user = sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUserEmail, sysUser.getUserEmail()));
            if (user != null && user.getId() != sysUser.getId()) {
                throw new RuntimeException("邮箱已被注册过，请换一个邮箱号重新输入");
            }
        }

        if (sysUser.getUserPhone() != null && sysUser.getUserPhone().length() > 0) {
            if (sysUser.getUserPhone().length() != 11) {
                throw new RuntimeException("请输入正确格式的手机号。");
            } else {
                String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
                Pattern p = Pattern.compile(regex);
                Matcher m = p.matcher(sysUser.getUserPhone());

                if (!m.matches()) {
                    throw new RuntimeException("请输入正确格式的手机号。");
                }
            }

            user = sysUserMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUserPhone, sysUser.getUserPhone()));
            if (user != null && user.getId() != sysUser.getId()) {
                throw new RuntimeException("手机号已被注册过，请换一个手机号重新输入");
            }
        }

        if (sysUser.getId() != null) {
            // 2）对要修改的对象加行锁
            SysUser result = sysUser.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, sysUser.getId()).last("for update"));

            // 3）判断该数据已经被改过没有
            if (result.getUpdateTime() != null) {
                if (sysUser.getUpdateTime() == null) {
                    throw new RuntimeException("保存数据失败，用户数据已经被其他用户改过。");
                } else {
                    if (sysUser.getUpdateTime().getTime() != result.getUpdateTime().getTime()) {
                        throw new RuntimeException("保存数据失败，用户数据已经被其他用户改过。");
                    }
                }
            }
        }

        user = UserUtil.getUser();
        Date updateTime = new Date();

        // 4)保存用户信息
        if (sysUser.getId() != null) {
            sysUser.setUpdateUser(user.getId());
            sysUser.setUpdateTime(updateTime);

            sysUser.updateById();
        } else {
            final String DEFAULT_PASSWORD = MD5Util.encode("123456");
            sysUser.setCreateUser(user.getId());
            sysUser.setCreateTime(updateTime);
            sysUser.setUserLoginpwd(DEFAULT_PASSWORD);
            sysUser.insert();
        }

        // 5）保存岗位用户信息
        if (sysUserExtend.getPostList() != null && sysUserExtend.getPostList().size() > 0) {
            List<SysPostUser> postUsers = sysPostUserMapper.selectList(new QueryWrapper<SysPostUser>().lambda().eq(SysPostUser::getUserId, sysUser.getId()));

            Map<String, SysPostUser> postUserMap = new HashMap<>();
            SysPostUser tmpSysPostUser = null;
            int idx = 0;

            if (postUsers != null && postUsers.size() > 0) {
                for (SysPostUser spu : postUsers) {
                    postUserMap.put(String.format("%d-%d", spu.getOrgId(), spu.getPostId()), spu);
                }
            }

            for (SysOrgExtend soe : sysUserExtend.getPostList()) {
                tmpSysPostUser = postUserMap.get(String.format("%d-%d", soe.getOrgId(), soe.getPostId()));

                if (tmpSysPostUser == null) {
                    tmpSysPostUser = new SysPostUser();
                    tmpSysPostUser.setUserId(sysUser.getId());
                    tmpSysPostUser.setMainFlag(idx == 0 ? 1 : 2);
                    tmpSysPostUser.setPostId(soe.getPostId());
                    tmpSysPostUser.setOrgId(soe.getOrgId());
                    tmpSysPostUser.setState(1);
                    tmpSysPostUser.setCreateUser(user.getId());
                    tmpSysPostUser.setCreateTime(updateTime);

                    tmpSysPostUser.insert();
                } else {
                    if (tmpSysPostUser.getState() == 1 && tmpSysPostUser.getUpdateTime() != null) {
                        if (soe.getUpdateTime() != null && tmpSysPostUser.getUpdateTime().getTime() != soe.getUpdateTime().getTime()) {
                            throw new RuntimeException("保存数据失败，岗位用户数据已经被其他用户改过。");
                        }
                    }

                    tmpSysPostUser.setMainFlag(idx == 0 ? 1 : 2);
                    tmpSysPostUser.setState(1);
                    tmpSysPostUser.setUpdateUser(user.getId());
                    tmpSysPostUser.setUpdateTime(updateTime);
                    tmpSysPostUser.updateById();

                    postUserMap.remove(String.format("%d-%d", soe.getOrgId(), soe.getPostId()));
                }

                idx++;
            }

            // 6)没有匹配上的岗位用户数据逻辑删除
            for (Map.Entry<String, SysPostUser> entry : postUserMap.entrySet()) {
                tmpSysPostUser = entry.getValue();

                tmpSysPostUser.setState(2);
                tmpSysPostUser.setUpdateUser(user.getId());
                tmpSysPostUser.setUpdateTime(updateTime);

                tmpSysPostUser.updateById();
            }
        }
    }

    public List<SysUserExtend> getAllUsersByOrgId(int id) {
        List<SysUserExtend> result = new ArrayList<>();
        List<SysPost> list = this.getPostListByOrgId(id);
/*        for (SysPost i : list) {
            SysUserExtend user = new SysUserExtend();
            user.setPostId(i.getId());
            List<SysUserExtend> userList = this.selectUserList(user);
            result.addAll(userList);
        }*/

        return result;
    }

    /*
     *取得指定机构编号的岗位一览
     *  */
    public List<SysPost> getPostListByOrgId(int i) {
        List<Integer> ids = new ArrayList<>();
        ids.add(i);

        // 取得所有子节点的编号一览
        List<SysOrg> list = sysOrgMapper.selectList(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getOrgState, 1));

        if (list != null && list.size() > 0) {

            ids = getAllClients(list, ids);
            ids.add(i);
        }

        List<SysPost> result = sysPostMapper.selectList(new QueryWrapper<SysPost>().lambda().in(SysPost::getOrgId, ids).eq(SysPost::getPostState, 1));

        return result;
    }

    /*
     * 递归查询指定orgId的子orgId的List
     * */
    private List<Integer> getAllClients(List<SysOrg> orgList, List<Integer> list) {
        List<Integer> result = new ArrayList<>();

        // 1)定义临时变量
        for (SysOrg tmpOrg : orgList) {
            if (tmpOrg.getOrgPid() != null && tmpOrg.getOrgPid() > 0 && list.contains(tmpOrg.getOrgPid())) {
                result.add(tmpOrg.getId());
            }
        }

        // 2)进行递归
        if (result.size() > 0) {
            result.addAll(getAllClients(orgList, result));
        }

        return result;
    }


    public List searchUpostNameList(String[] arr) {
        List list = new ArrayList();
        for (String i : arr) {
            SysUserExtend userExtend = sysUserExtendMapper.selectUpostName(Integer.parseInt(i));
//            list.add(userExtend.getPostName());
        }
        return list;
    }

    public List<SysUser> selectRecycleList(SysUser user) {
        List<SysUser> result = sysUserMapper.selectList(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUserState, 2));
        return result;
    }

    @Transactional
    public int recycle(List<SysUser> sysUserList) {
        Map<Integer, SysUser> userMap = new HashMap<>();
        // 2）对要修改的对象加行锁
        List<Integer> idList = new ArrayList<>();
        for (SysUser sd : sysUserList) {
            userMap.put(sd.getId(), sd);
            idList.add(sd.getId());
        }

        List<SysUser> result = sysUserMapper.selectList(new QueryWrapper<SysUser>().lambda().in(SysUser::getId, idList).last("for update"));

        if (result != null && result.size() > 0) {
            SysUser tmpUser = null;

            SysUser user1 = UserUtil.getUser();
            Date updateTime = new Date();

            for (SysUser sd : result) {
                tmpUser = userMap.get(sd.getId());

                // 3）判断该数据已经被改过没有
                if (sd.getUpdateTime() != null) {
                    if (tmpUser.getUpdateTime() == null) {
                        throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                    } else {
                        if (sd.getUpdateTime().getTime() != tmpUser.getUpdateTime().getTime()) {
                            throw new RuntimeException("删除数据失败，数据已经被其他用户改过。");
                        }
                    }
                }
            }

            SysUser sysUser = new SysUser();
            sysUser.setUpdateUser(user1.getId());
            sysUser.setUpdateTime(updateTime);
            sysUser.setUserState(1);
            sysUserMapper.update(sysUser, new UpdateWrapper<SysUser>().lambda().in(SysUser::getId, idList));

        }
        return 0;
    }



}
